/**
 * @class Spark.Tree
 * @extends Spark.Component
 * <p>树形组件.
 * @author njq.niu@hand-china.com
 * @constructor
 * @param {Object} config 配置对象. 
 */
$S.Tree = Ext.extend($S.ViewComponent,{
    showSkeleton: true,
    sw:18,
    constructor: function(config){
        $S.Tree.superclass.constructor.call(this,config);
        this.context = config.context||'';
    },
    initComponent:function(config){
        this.nodeHash = {};
        $S.Tree.superclass.initComponent.call(this, config);
        this.body = this.wrap.child('div[stype=tree.body]');
    },
    initBind : function(){
        if(this.bt) this.bind(this.bt)
    },
    processListener: function(ou){
        $S.Tree.superclass.processListener.call(this,ou);
        this.wrap[ou]('click', this.onClick, this)
                 [ou]('dblclick',this.onDblclick, this);
    },
    initEvents:function(){
        $S.Tree.superclass.initEvents.call(this);
        this.addEvents(
        /**
         * @event render
         * tree渲染事件.
         */
        'render',
        /**
         * @event collapse
         * 节点折叠事件.
         */
        'collapse',
        /**
         * @event expand
         * 节点展开事件.
         */
        'expand',
        /**
         * @event click
         * 点击事件.
         * @param {Spark.Record} record 选中的Record对象
         * @param {Spark.Tree.TreeNode} node 节点对象
         */
        'click',
        /**
         * @event dblclick
         * 鼠标双击事件.
         * @param {Spark.Tree} tree tree组件
         * @param {Spark.Record} record 当前record.
         * @param {Spark.Tree.TreeNode} node 节点对象
         */
        'dblclick');
    },
    destroy : function(){
        $S.Tree.superclass.destroy.call(this);
    },
    processDataSetLiestener: function(ou){
        var ds = this.dataset;
        if(ds){
            ds[ou]('update', this.onUpdate, this);
            ds[ou]('load', this.onLoad, this);
            ds[ou]('indexchange', this.onIndexChange, this);
        }
    },
    bind: function(ds){
        if(typeof(ds)==='string'){
            ds = $(ds);
            if(!ds) return;
        }
        var sf = this;
        sf.dataset = ds;
        sf.processDataSetLiestener('on');
        if(ds.datas.length >0)
        Ext.onReady(function(){
            sf.onLoad();
        })
    },
    onUpdate : function(ds, record, name, value){
        if(this.parentField == name || name == this.sequenceField){
            this.onLoad();
        }else{
            var node = this.nodeHash[record.id];
            if(node)node.paintText();
        }
    },
    onIndexChange:function(ds, record){
        var node = this.nodeHash[record.id];
        if(node)this.setFocusNode(node);
    },
    onDblclick : function(e,t){
        var elem = Ext.fly(t).findParent('td');
        if(!elem)return;
        var _type = elem['_type_'];
        if(typeof(_type) === undefined){
            return;
        }
        if(_type == 'icon' || _type == 'text'){
            elem = Ext.fly(e.target).findParent('div.s_node');
            if(!elem)return;
            var node = this.nodeHash[elem.indexId];
//            if(node && node.childNodes.length){
//                if(node.isExpand){
//                    node.collapse();
//                    this.fireEvent('collapse', this, node);
//                }else{
//                    node.expand();
//                    this.fireEvent('expand', this, node);
//                }
//            }
            var ds = this.dataset,r = node.record;
            ds.locate(ds.indexOf(r)+1,true);
            this.fireEvent('dblclick', this, r, node);
        }
    },
    onClick : function(e){
        e.stopEvent();
        var elem = Ext.fly(e.target).findParent('td');
        if(!elem)return;
        var _type = elem['_type_'];
        if(typeof(_type) === undefined){
            return;
        }
        elem = Ext.fly(e.target).findParent('div.s_node');
        if(!elem)return;
        var node = this.nodeHash[elem.indexId ];
        if(_type == 'clip'){
            if(elem.indexId!=null){             
                if(node.isExpand){
                    node.collapse();
                    this.fireEvent('collapse', this, node);
                }else{
                    node.expand();
                    this.fireEvent('expand', this, node);
                }
            }
        }else if(_type == 'icon' || _type == 'text'){
            this.setFocusNode(node);
            this.dataset.locate(this.dataset.indexOf(node.record)+1,true);
            this.fireEvent('click', this, node.record, node);
        }else if(_type == 'checked'){
            node.onCheck();
        }
    },
    getRootNode : function(){
        return this.root;
    },
    setRootNode : function(node){
        this.root = node;
        node.ownerTree = this;
        this.registerNode(node);
        node.cascade((function(node){
            this.registerNode(node);
        }),this);
    },
    /**
     * 根据id获取节点对象
     * @param {Number} id 节点id
     * @return {Spark.Tree.TreeNode} node 节点对象
     */
    getNodeById : function(id){
        return this.nodeHash[id];
    },
    registerNode : function(node){
        this.nodeHash[node.id] = node;
    },
    unregisterNode : function(node){
        delete this.nodeHash[node.id];
    },
    /**
     * 设置节点焦点
     * @param {Spark.Tree.TreeNode} node 节点对象.
     */
    setFocusNode : function(node){
        if(this.focusNode){
            this.focusNode.unselect();
        }
        this.focusNode = node;
        if(node.parentNode){
            node.parentNode.expand();
        }
        node.select();
    },
    createNode: function(record){
        return {
            record:record,
            children:[]
        }
    },
    buildTree: function(){
        var array = [];
        var map1 = {};
        var map2 = {};
        var datas = this.dataset.datas;
        var l = datas.length;
        for(var i=0;i<l;i++){
            var record = datas[i];
            var id = record.get(this.idField);
            var node = this.createNode(record);
            node.checked = (node.record.get(this.checkField) == "Y") ? 1 : 0;            
            node.expanded = !Ext.isEmpty(this.expandAll) ? this.expandAll :  node.record.get(this.expandField) == "Y";
            map1[id] = node;
            map2[id] = node;
        }
        for(var key in map2){
            var node = map2[key];
            var record = node.record;
            var pid = record.get(this.parentField);
            var parent = map2[pid];
            if(parent){
                parent.children.add(node);
                delete map1[key];
            }
        }
        for(var key in map1){
            var node = map2[key];
            array.add(node);
        }
        var rtnode = null;
        if(array.length == 1){
            this.showRoot = true;
            rtnode = array[0];
        }else{
            var data = {};
            data[this.displayField] = '_root';
            var record =  new Spark.Record(data);
            record.ds = this.dataset;
            var root = { 
                'record':record,
                'children':[]
            }
            for(var i=0;i<array.length;i++){
                root['children'].add(array[i]);
            }
            this.showRoot = false;
            rtnode = root;
        }
        
        var process = function(item){
            var children = item.children;
            var count = children.length;
            for(var i=0;i<count;i++){
                var node = children[i]
                if(node.children.length >0){
                    process(node);
                } 
            }                     
            
            var checked1 = 0;
            for(var i=0;i<count;i++){
                var checked = children[i].checked;
                if(checked==1){
                    checked1++;
                }
            }
            if(checked1==0){
                item.checked = 0;
            }else if(count==checked1){
                item.checked = 1;
            }else {
                item.checked = 2;
            }
        }
        
        for(var i=0;i<array.length;i++){
            var item = array[i];
            process(item)
        }
        
        
        this.sortChildren(rtnode.children,this.sequenceField);
        return rtnode;
    },
    sortChildren : function(children,sequence){
        if(sequence){
            var m = Number.MAX_VALUE;
            children.sort(function(a, b){
                return parseFloat(a.record.get(sequence)||m) - parseFloat(b.record.get(sequence)||m);
            });
        }else{
            children.sort();
        }
        Ext.each(children,function(n){
            this.sortChildren(n.children,sequence)
        },this);
    },
    createTreeNode : function(item){
        return new $S.Tree.TreeNode(item);
    },
    onLoad : function(){
        var root = this.buildTree();
        if(!root) {
            return;
        }
        
        var node = this.createTreeNode(root);
        this.setRootNode(node); 
        this.body.update('');
        if(this.dataset.datas.length>0)
        this.root.render();
        this.fireEvent('render', this,root);
    },
    getIconByType : function(type){
        return type;
    },
    onNodeSelect : function(el){
        Ext.fly(el[this.displayField+'_td']).addClass('node-select');
//        el[this.displayField+'_td'].style.backgroundColor='#ffffd5';
    },
    onNodeUnSelect : function(el){
       Ext.fly(el[this.displayField+'_td']).removeClass('node-select');
//       el[this.displayField+'_td'].style.backgroundColor='';
    }
})
/**
 * @class Spark.Tree.TreeNode
 * @extends Spark.Component
 * <p>树节点对象.
 * @author njq.niu@hand-china.com
 * @constructor 
 */
$S.Tree.TreeNode = function(data) {
    this.init(data)
}
$S.Tree.TreeNode.prototype={
    init : function(data){
        this.data = data;
        this.record = data.record;
        this.els = null;
        this.id = this.record.id;
        this.parentNode = null;
        this.childNodes = [];
        this.lastChild = null;
        this.firstChild = null;
        this.previousSibling = null;
        this.nextSibling = null;
        this.childrenRendered = false;
        this.isExpand = data.expanded;//false;    
        this.checked = data.checked;
        Ext.each(data.children,function(node){
            this.appendChild(this.createNode(node));
        },this);
    },
    createNode : function(item){
        return new $S.Tree.TreeNode(item);
    },
    createCellEl : function(df){     
    },
    initEl : function(){
        var tree = this.getOwnerTree(),df = tree.displayField,text = this.record.get(df),div = document.createElement('div'),
            child = document.createElement('div'),table = document.createElement('table'),tbody = document.createElement('tbody'),
            tr = document.createElement('tr'),checkbox;
        div.className = 's_node';
        table.border=0;
        table.cellSpacing=0;
        table.cellPadding=0;
        this.els = {element:div,itemNodeTable:table,itemNodeTbody:tbody,itemNodeTr:tr,child:child};
        tbody.appendChild(tr);
        table.appendChild(tbody);
        div.appendChild(table);
        if(tree.showSkeleton){
            var line = tr.insertCell(-1),clip = tr.insertCell(-1),icon = this.icon? document.createElement('img') : null,iconTd = tr.insertCell(-1);
            checkbox = tr.insertCell(-1);
            line['_type_'] ='line';
            line.className ='line';
            clip['_type_'] ='clip';
            clip.innerHTML = '&#160';
            iconTd['_type_'] ='icon';
            checkbox['_type_'] ='checked';
            checkbox.innerHTML = '&#160';
            iconTd.className='node-icon';
            if(icon) {
                iconTd.appendChild(icon);
            }else {
                iconTd.innerHTML = '&#160';
            }
            Ext.apply(this.els,{line:line,clip:clip,icon:icon,iconTd:iconTd,checkbox:checkbox})
            var td = tr.insertCell(-1);
            td['_type_'] ='text';
            this.els[df + '_td'] = td;
            this.createCellEl(df);
            td.className='node-text'
        }
        
        div.noWrap='true';
        
        if(tree.showCheckBox === false && checkbox) {
            checkbox.style.display='none';
        }
        if(this.isRoot() && text=='_root'){
            table.style.display='none';
        }
        div.appendChild(child);
        child.className= 's_child';
        child.style.display='none';
        
    },
    render : function(){
        var tree = this.getOwnerTree();
        this.icon = this.record.get(tree.iconField);
        if(!this.els){
            this.initEl();
        }
        if(this.isRoot()){
            tree.body.appendChild(this.els['element']);
            if(this.getOwnerTree().showRoot == false && this.getOwnerTree().showSkeleton)
            this.els['iconTd'].style.display=this.els['checkbox'].style.display=this.els[tree.displayField+'_td'].style.display='none';
            this.expand();
        }else{
            this.parentNode.els['child'].appendChild(this.els['element']);
            if(this.isExpand)
            this.expand();
        }
        this.initColumns();
        this.paintPrefix();
        this.els['element'].indexId = this.id;
        this.paintCheckboxImg();
    },
    initColumns : function(){},
    paintPrefix : function(){
        if(!this.getOwnerTree().showSkeleton) return;
        this.paintLine();
        this.paintClipIcoImg();
        this.paintCheckboxImg();
        this.paintIconImg();
        this.paintText();
    },
    paintLine : function(){
        var ownerTree = this.getOwnerTree();
        var pathNodes = this.getPathNodes(),
            w = (pathNodes.length-2)*ownerTree.sw,
            line = this.els['line'];
        line.innerHTML = '';
        Ext.fly(line).setStyle('width',Math.max(w,0)+'px');
        if(w==0){
            line.style.display='none';
        }
        for(var i = 1 ,count = pathNodes.length-1 ; i < count ; i++){
            var node = pathNodes[i],
                ld = document.createElement('div');
            ld.className = node.isLast()?'node-empty':'node-line';
            //Ext.fly(ld).setWidth(ownerTree.sw);
            line.appendChild(ld);
        }
    },
    paintClipIcoImg : function(){
        var ownerTree = this.getOwnerTree(),icon = 'empty',clip = this.els['clip'];
        if(!ownerTree.showSkeleton) return;
        if(this.isRoot()){
            clip.style.display='none';//不显示根节点的clip
            return;
        } else {
            if(this.isLeaf()){
                if(this.isLast()){
                    icon = 'joinBottom';
                } else if(this.isFirst()){
                    icon = 'joinTop';
                }else{
                    icon = 'join';
                }
            }else{
                if(this.isExpand){
                    if(this.isLast()){
                        icon = 'minusBottom';
                    } else if(this.isFirst()){
                        icon = 'minusTop';
                    }else{
                        icon = 'minus';
                    }
                }else{
                    if(this.isLast()){
                        icon = 'plusBottom';
                    } else if(this.isFirst()){
                        icon = 'plusTop';
                    }else{
                        icon = 'plus';
                    }
                }
            }
        };
        clip.className = 'node-clip clip-' + icon;
    },
    paintIconImg : function(){
        var ownerTree = this.getOwnerTree();
        if(!ownerTree.showSkeleton) return;
        var data = this.data,icon = data.icon,eicon = this.els['icon'],iconTd = this.els['iconTd'];
        if(!icon){
            var type = data.type;
            if(type){
                icon = ownerTree.getIconByType(type);
            }
            if(!icon){
                if(this.isRoot()){
                    icon = 'root';
                }else if(this.isLeaf()){
                    icon = 'node';
                }else if(this.isExpand){
                    icon = 'folderOpen';
                }else{
                    icon = 'folder';
                }
            }
        }
        if(this.icon) {
            eicon.className = 'node-icon';
            eicon.src = ownerTree.context + this.icon;
        }else{
            iconTd.className = 'node-icon icon-' + icon;
        }
    },
    paintCheckboxImg : function(){
        var ownerTree = this.getOwnerTree();    
        if(!ownerTree.showSkeleton) return;
        var checked = this.checked;
        if(this.els){
            this.els['checkbox'].className = ((checked==2)?'checkbox2':(checked==1)?'checkbox1':'checkbox0');
        }
    },  
    paintText : function(){
        if(!this.els) return;
        var tree = this.getOwnerTree();
        var text = this.record.get(tree.displayField)
        if(!Ext.isEmpty(tree.renderer)){
            var renderer = window[tree.renderer];
            if(renderer)
            text = renderer.call(this, text, this.record, this);
        }
        this.syncWidth(tree,text);
        var tel =this.els[tree.displayField+'_td'];
        if(tel && text)tel.innerHTML=text;
        
    },
    syncWidth : function(tree,text){
        var w = ((tree.showCheckBox ? 1 : 0) +this.getPathNodes().length)*tree.sw;
        w = w+$S.TextMetrics.measure(text).width + 6;//padding-left(2)+padding-right(2)+border-left(1)+border-right(1)
        Ext.fly(this.els['itemNodeTable']).setWidth(w);
    },
    
    paintChildren : function(){
        if(!this.childrenRendered){
//          this.els['child'].innerHTML = '';
            this.childrenRendered = true;
            Ext.each(this.childNodes,function(node){
                node.render();
            });
        };
    },
    /**
     * 折叠收起
     */
    collapse : function(){
        this.isExpand=false;
        if(!this.isRoot())
        this.record.set(this.getOwnerTree().expandField,"N");
        this.els['child'].style.display='none';
        this.paintIconImg();
        this.paintClipIcoImg();
        this.refreshDom();
    },
    /**
     * 展开
     */
    expand : function(){
        if(!this.isLeaf()&&this.childNodes.length>0){
            if(!this.isRoot())
            this.record.set(this.getOwnerTree().expandField,"Y");
            this.isExpand=true;
            this.paintChildren();
            this.els['child'].style.display='block';
        }
        this.paintIconImg();
        this.paintClipIcoImg();
        this.refreshDom();
    },
    refreshDom : function(){
        this.getOwnerTree().wrap.addClass('a').removeClass('a');
    },
    /**
     * 选中节点
     */
    select : function(){
        this.isSelect = true;
        this.getOwnerTree().onNodeSelect(this.els);
    },
    /**
     * 取消选择
     */
    unselect : function(){
        this.isSelect = false;
        this.getOwnerTree().onNodeUnSelect(this.els);
    },
    getEl :  function(){
        return this.els;
    },
    setCheckStatus : function(checked){
        var c;
        if(checked==2||checked==3){
            var childNodes = this.childNodes,count = childNodes.length;
            if(count==0){
                c=checked==2?0:1;
            }else{
                var checked1 = 0,checked2 = 0;
                for(var i=0;i<count;i++){
                    var checked = childNodes[i].checked;
                    if(checked==1){
                        checked1++;
                    }else if(checked==2){
                        checked2++;
                    }
                }
                c = (childNodes.length==checked1) ? 1 : (checked1>0||checked2>0) ? 2 : 0;
            }
        }else{
            c=checked;
        }
        this.checked = c;
        if(!this.isRoot()) {
            this.record.set(this.getOwnerTree().checkField, (c==1||c==2) ? "Y" : "N");
        }
        this.paintCheckboxImg();
    },
    setCheck : function(cked){
        var a = cked?1:0,b=a+2;
        this.cascade(function(node){
            node.setCheckStatus(a);
        });
        this.bubble(function(node){
            node.setCheckStatus(b);
        });
    },
    onCheck : function(){
        this.setCheck(this.checked == 0);
    },
    /**
     * 是否是根节点
     * @return {Boolean} isroot 是否根节点.
     */
    isRoot : function(){
        return this.ownerTree && this.ownerTree.root === this;
    },
    /**
     * 是否叶子节点
     * @return {Boolean} isleaf 是否叶子节点.
     */
    isLeaf : function(){
        return this.childNodes.length===0;
    },
    /**
     * 是否是最后一个节点.
     * @return {Boolean} islast 是否是最后.
     */
    isLast : function(){
        return (!this.parentNode ? true : this.parentNode.childNodes[this.parentNode.childNodes.length-1] == this);
    },
    /**
     * 是否是第一个
     * @return {Boolean} isfirst 是否是第一个.
     */
    isFirst : function(){
        var tree = this.getOwnerTree();
        return (this.parentNode== tree.getRootNode()&&!tree.showRoot&&(this.parentNode.childNodes[0] == this));
    },
    hasChildNodes : function(){
        return !this.isLeaf() && this.childNodes.length > 0;
    },
    setFirstChild : function(node){
        this.firstChild = node;
    },
    setLastChild : function(node){
        this.lastChild = node;
    },
    appendChild : function(node){
        var multi = false;
        if(node instanceof Array){
            multi = node;
        }else if(arguments.length > 1){
            multi = arguments;
        }
        if(multi){
        for(var i = 0, len = multi.length; i < len; i++) {
                this.appendChild(multi[i]);
            }
        }else{
            //>>beforeappend
            var oldParent = node.parentNode;
            //>>beforemove
            if(oldParent){
                oldParent.removeChild(node);
            }
            var index = this.childNodes.length;
            if(index == 0){
                this.setFirstChild(node);
            }
            this.childNodes.push(node);
            node.parentNode = this;
            //
            var ps = this.childNodes[index-1];
            if(ps){
                node.previousSibling = ps;
                ps.nextSibling = node;
            }else{
                node.previousSibling = null;
            }
            node.nextSibling = null;
            this.setLastChild(node);
            node.setOwnerTree(this.getOwnerTree());
            //>>append
            //if(oldParent) >>move

            if(node && this.childrenRendered){
                node.render();
                if(node.previousSibling){
                    node.previousSibling.paintPrefix();//paintLine();
                }
            }
            if(this.els){
                this.paintPrefix();
            }
            return node;//true
        }
    },
    removeChild : function(node){
        var index = this.childNodes.indexOf(node);
        if(index == -1){
            return false;
        }
        //>>beforeremove
        this.childNodes.splice(index, 1);
        if(node.previousSibling){
            node.previousSibling.nextSibling = node.nextSibling;
        }
        if(node.nextSibling){
            node.nextSibling.previousSibling = node.previousSibling;
        }
        if(this.firstChild == node){
            this.setFirstChild(node.nextSibling);
        }
        if(this.lastChild == node){
            this.setLastChild(node.previousSibling);
        }
        node.setOwnerTree(null);
        //clear
        node.parentNode = null;
        node.previousSibling = null;
        node.nextSibling = null;
        //>>remove UI
        if(this.childrenRendered){
            if(node.els&&node.els['element']){
                this.els['child'].removeChild(node.els['element'])  
            }
            if(this.childNodes.length==0){
                this.collapse();
            }
        }
        if(this.els){
            this.paintPrefix();
        }
        return node;
    },
    insertBefore : function(node, refNode){
        if(!refNode){
            return this.appendChild(node);
        }
        //移动位置是自身位置(不需要移动)
        if(node == refNode){
            return false;
        }
        var index = this.childNodes.indexOf(refNode);
        var oldParent = node.parentNode;
        var refIndex = index;
        //是子节点，并且是向后移动
        if(oldParent == this && this.childNodes.indexOf(node) < index){
            refIndex--;
        }
        if(oldParent){
            oldParent.removeChild(node);
        }
        //设置节点间关系
        if(refIndex == 0){
            this.setFirstChild(node);
        }
        this.childNodes.splice(refIndex, 0, node);
        node.parentNode = this;
        var ps = this.childNodes[refIndex-1];
        if(ps){
            node.previousSibling = ps;
            ps.nextSibling = node;
        }else{
            node.previousSibling = null;
        }
        node.nextSibling = refNode;
        refNode.previousSibling = node;
        node.setOwnerTree(this.getOwnerTree());
        return node;
    },
    replaceChild : function(newChild, oldChild){
        this.insertBefore(newChild, oldChild);
        this.removeChild(oldChild);
        return oldChild;
    },
    indexOf : function(child){
        return this.childNodes.indexOf(child);
    },
    getOwnerTree : function(){
        if(!this.ownerTree){
            var p = this;
            while(p){
                if(p.ownerTree){
                    this.ownerTree = p.ownerTree;
                    break;
                }
                p = p.parentNode;
            }
        }
        return this.ownerTree;
    },
    setOwnerTree : function(tree){
        if(tree != this.ownerTree){
            if(this.ownerTree){
                this.ownerTree.unregisterNode(this);
            }
            this.ownerTree = tree;
            var cs = this.childNodes;
            for(var i = 0, len = cs.length; i < len; i++) {
                cs[i].setOwnerTree(tree);
            }
            if(tree){
                tree.registerNode(this);
            }
        }
    },
    getPathNodes : function(){
        var nodes = [];
        for(var parent=this; parent!=null; parent=parent.parentNode){nodes.push(parent);};
        return nodes.reverse();
    },
    bubble : function(fn, scope, args){
        var p = this;
        while(p){
            if(fn.call(scope || p, args || p) === false){
                break;
            }
            p = p.parentNode;
        }
    },
    cascade : function(fn, scope, args){
        if(fn.call(scope || this, args || this) !== false){
            var cs = this.childNodes;
            for(var i = 0, len = cs.length; i < len; i++) {
                cs[i].cascade(fn, scope, args);
            }
        }
    },
    findChild : function(attribute, value){
        var cs = this.childNodes;
        for(var i = 0, len = cs.length; i < len; i++) {
            if(cs[i].attributes[attribute] == value){
                return cs[i];
            }
        }
        return null;
    },
    findChildBy : function(fn, scope){
        var cs = this.childNodes;
        for(var i = 0, len = cs.length; i < len; i++) {
            if(fn.call(scope||cs[i], cs[i]) === true){
                return cs[i];
            }
        }
        return null;
    },
    sort : function(fn, scope){
        var cs = this.childNodes;
        var len = cs.length;
        if(len > 0){
            var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
            cs.sort(sortFn);
            for(var i = 0; i < len; i++){
                var n = cs[i];
                n.previousSibling = cs[i-1];
                n.nextSibling = cs[i+1];
                if(i == 0){
                    this.setFirstChild(n);
                }
                if(i == len-1){
                    this.setLastChild(n);
                }
            }
        }
    }
};